package icu.lookyousmileface.matchlock;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author starrysky
 * @title: RepeatLock
 * @projectName Juc_Pro
 * @description: 可重复锁,拿到大门的锁相当于拿到卧室的钥匙
 * @date 2021/1/308:56 下午
 */
public class RepeatLock {
    public static void main(String[] args) {

        Phone phone = new Phone();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                5,
                Runtime.getRuntime().availableProcessors(),
                5,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );

        try {
            threadPoolExecutor.execute(()->{
                phone.sms();
                System.out.println(Thread.currentThread().getName()+"=>ok");
            });

            threadPoolExecutor.execute(()->{
                phone.sms();
                System.out.println(Thread.currentThread().getName()+"=>ok");
            });
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            threadPoolExecutor.shutdown();
        }

    }

    static class Phone {
        ReentrantLock reentrantLock = new ReentrantLock();

        public void sms() {
            /**
             * 上锁和解锁要配对否则会造成死锁
             */
            reentrantLock.lock();
            try {
                System.out.println("Sms");
                call();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                reentrantLock.unlock();
            }
        }

        public void call() {
            reentrantLock.lock();
            try {
                System.out.println("call");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                reentrantLock.unlock();
            }
        }
    }
}
